import { Html, useAnimations } from "@react-three/drei";
import { useLoader } from "@react-three/fiber";
import { Select } from "@react-three/postprocessing";
import { ReactNode, Ref, useRef, useState } from "react";
import { Group, Mesh } from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { IModel } from "../interfaces";
import { useDebounce } from "../common/hooks/useDebounce";
import { debounce } from "lodash";

type InteractiveModelProps = {
    model: IModel
} & JSX.IntrinsicElements["group"]


export function InteractiveModel(props: InteractiveModelProps) {
    const groupRef = useRef<Group>()
    const { scene, animations } = useLoader(GLTFLoader, `/api/${props.model.modelFilePath}`)
    const { names, actions } = useAnimations(animations, groupRef)
    const meshes = scene.children as Mesh[]
    const [hover, setHover] = useState('')
    const assembleActions = names.filter(e => e.includes("_assemble"))
    const disassembleActions = names.filter(e => e.includes("_disassemble"))



    const playActionsOnce = (needActionsNames: string[]) => {
        names.forEach((e) => {
            actions[e]?.stop()
        })
        needActionsNames.forEach((e) => {
            actions[e]!.clampWhenFinished = true
            actions[e]!.reset().play().setLoop(2200, 1)
        })
    }

    const content = meshes.map((e) => {
        const meshData = props.model.meshes.find(el => el.originalMeshName == e.name)
        const selected = hover == e.name && meshData?.interactive
        // const debouncedSelected = useDebounce(selected)
        return (
            <Select key={e.name} enabled={selected}>
                <mesh
                    onPointerOver={(event) => {
                        event.stopPropagation()
                        setHover(e.name)
                    }}
                    onPointerOut={(event) => {
                        event.stopPropagation()
                        setHover('')
                    }}
                    name={e.name}
                    position={e.position}
                    geometry={e.geometry}
                    material={e.material}
                    receiveShadow
                    castShadow
                >
                    {selected  &&
                        <Html
                            as="div"
                            className='border-2 border-black rounded p-1 text-black w-fit pointer-events-none bg-white'
                        >
                            <div className='flex'>
                                <h1>Название:</h1>
                                <p className='whitespace-nowrap'>
                                    {meshData?.name}
                                </p>
                            </div>
                            <div className='flex'>
                                <h1>Описание:</h1>
                                <p className='whitespace-nowrap'>
                                    {meshData?.description}
                                </p>
                            </div>
                        </Html>

                    }
                </mesh>

            </Select>
        )
    })

    return (
        <group ref={groupRef as Ref<Group>} dispose={null}>
            <group name="Scene">
                {content}
            </group>
        </group>

    );
}

